// Refer: https://github.com/tkhr-sait/timekeeper/blob/master/src/command/say.go
// Only for Windows OS

package windows

import (
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"runtime"
)

// TTS 提供Windows系统下的文本转语音(TTS)功能。
// 使用Windows SAPI(语音API)实现。
//
// 字段说明:
//   - tempFile: 临时VBS脚本文件路径
//   - rate: 语速参数(1-10)
//   - inited: 是否已初始化
type TTS struct {
	tempFile string // content
	rate     string // speed
	inited   bool
}

// Init 初始化TTS引擎。
// 创建临时VBS脚本文件用于语音合成。
//
// 注意:
//   - 仅在Windows系统下有效
//   - 默认语速为3(中等)
//   - 自动创建临时脚本文件
func (self *TTS) Init() {
	if self.rate == "" {
		self.rate = "3" // Defalut
	}
	if runtime.GOOS == "windows" {
		tmpfile, _ := ioutil.TempFile("", "tempTTS_")
		script := `
		set TTS = CreateObject("SAPI.SpVoice")
		TTS.rate=` + self.rate + `
		TTS.Speak(WScript.Arguments(0))
		`
		tmpfile.WriteString(script)
		tmpfile.Close()
		self.tempFile = tmpfile.Name() + ".vbs"
		os.Rename(tmpfile.Name(), self.tempFile)
	}
	self.inited = true
}

// RemoveTempFile 删除临时VBS脚本文件。
// 应在程序退出前调用以清理资源。
func (self *TTS) RemoveTempFile() {
	if runtime.GOOS == "windows" {
		os.Remove(self.tempFile)
	}
}

// Set speed.
// SetRate 设置语音合成速度。
//
// 参数:
//   - rate: 语速值(1-10)
//
// 注意:
//   - 1为最慢，10为最快
//   - 默认值为3(中等)
func (self *TTS) SetRate(rate int) {
	self.rate = fmt.Sprintf("%d", rate)
}

// say 执行语音合成并返回命令对象。
//
// 参数:
//   - message: 要合成的文本
//
// 返回值:
//   - *exec.Cmd: 语音合成命令对象
//
// 注意:
//   - 自动初始化
//   - 非Windows系统会调用系统say命令
func (self *TTS) say(message string) *exec.Cmd {
	if !self.inited {
		self.Init()
	}
	if runtime.GOOS == "windows" {
		return exec.Command("cscript", "//Nologo", self.tempFile, message)
	} else {
		return exec.Command("say", message)
	}
}

// SayNotWait 异步执行语音合成(不等待完成)。
//
// 参数:
//   - message: 要合成的文本
//
// 注意:
//   - 立即返回不等待语音完成
//   - 自动初始化
func (self *TTS) SayNotWait(message string) {
	self.say(message).Start()
}

// SayWait 同步执行语音合成(等待完成)。
//
// 参数:
//   - message: 要合成的文本
//
// 注意:
//   - 等待语音合成完成后返回
//   - 自动初始化
func (self *TTS) SayWait(message string) {
	self.say(message).Run()
}

func TestTTS() {
	var tts TTS
	tts.SayNotWait("Hello")
}
